﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using Logger = SetupLauncher.Domain.Logger;
using Config = SetupLauncher.Domain.Configuration;
using Entity = SetupLauncher.Domain.Entity;
using System.Threading;
using SetupLauncher.Domain.Exceptions;

namespace SetupLauncher.UI
{
    public partial class Main : Form, Logger.ILoggable
    {
        List<Entity.Product> _products;

        public Main()
        {
            InitializeComponent();
            try
            {
                Config.IConfiguration _configuration = Config.ConfigurationFactory.Create(this);

                string fileName = System.Configuration.ConfigurationSettings.AppSettings["fileName"];
                string path = System.IO.Path.Combine(Application.StartupPath, fileName);
                if (!string.IsNullOrEmpty(path))
                {
                    _configuration.Load(path);
                    _products = _configuration.Products;
                }
                else
                {
                    MessageBox.Show("Não foi possível encontrar o parâmetro de configuração");
                }
                int height = this.Height;
                int width = this.Width;
                this.Resize += (s, e) =>
                {
                    this.Height = height;
                    this.Width = width;
                };
            }
            catch (Exception ex)
            {
                WriteAlert(ex.Message);
            }
        }

        private void ListProducts()
        {
            foreach (var product in _products.Where(p => p != null))
                cmbProduct.AddItem(product);
        }

        private void ListPerfils()
        {
            cmbPerfils.AddItem(Entity.PerfilType.Desenvolvimento);
            cmbPerfils.AddItem(Entity.PerfilType.Teste);
            cmbPerfils.SelectedIndex = 0;
        }

        private void ListEnvironment()
        {
            if (cmbProduct.GetSelectedItem() == null)
                return;

            Entity.Product product = cmbProduct.GetSelectedItem() as Entity.Product;
            if (product == null)
                return;

            foreach (Entity.Environment environment in product.Environments.Where(e => e != null))
                cmbEnvironment.AddItem(environment);
        }

        private void ListVersions()
        {
            if (cmbEnvironment.GetSelectedItem() == null)
                return;

            Entity.Environment env = cmbEnvironment.GetSelectedItem() as Entity.Environment;
            if (env == null)
                return;

            foreach (Entity.Version version in env.Versions.Where(v => v != null))
                cmbVersions.AddItem(version);

            lblVersion.Enabled = env.LoadAllVersions;
            cmbVersions.Enabled = env.LoadAllVersions;

            if (cmbVersions.Items.Count == 1)
                cmbVersions.SelectedIndex = 0;
        }

        private void Execute()
        {
            this.SetControlBox(false);
            try
            {
                lblLog.SetVisible(true);

                Entity.Product produt = cmbProduct.GetSelectedItem() as Entity.Product;
                Entity.Environment environment = cmbEnvironment.GetSelectedItem() as Entity.Environment;
                Entity.PerfilType type = (Entity.PerfilType)cmbPerfils.GetSelectedItem();
                Entity.Version version = cmbVersions.GetSelectedItem() as Entity.Version;

                string supportFolderExternalSetup = AppDomain.CurrentDomain.BaseDirectory + @"\Support";
                var setup = new SetupLauncher.Domain.Logic.Setup(supportFolderExternalSetup, produt, environment, type, version, this);

                pgbStatus.SetProgressBarStyle(ProgressBarStyle.Marquee);
                btnExecutar.SetEnabled(false);

                setup.Execute();

                lblLog.SetText("Processo Finalizado... Aguardando a Inicialização do Setup...");
                //btnExecutar.SetText("Fechar");
            }
            catch (ValidationException val)
            {
                WriteAlert(val.Validations);
            }
            catch (Exception ex)
            {
                WriteException(ex.Message);
            }
            btnExecutar.SetEnabled(true);
            pgbStatus.SetProgressBarStyle(ProgressBarStyle.Blocks);
            this.SetControlBox(true);
        }

        private void SetInformations()
        {
            if (cmbProduct.Items.Count == 1)
            {
                cmbProduct.SelectedIndex = 0;
                if (cmbEnvironment.Items.Count == 1)
                {
                    cmbEnvironment.SelectedIndex = 0;
                    if (cmbVersions.Items.Count == 1)
                    {
                        cmbVersions.SelectedIndex = 0;
                    }
                }
            }

            if (cmbPerfils.Items.Count > 0)
                cmbPerfils.SelectedIndex = (int)Entity.PerfilType.Teste;
        }

        #region [ Log ]

        public void Write(string message)
        {
            lblLog.SetText(message);
        }

        public void WriteException(string message)
        {
            MessageBox.Show(message, this.Text, MessageBoxButtons.OK, MessageBoxIcon.Error);
        }

        public void WriteAlert(List<Validation> validations)
        {
            StringBuilder sb = new StringBuilder();
            sb.AppendLine("Foram encontrados os seguintes problemas:");
            foreach (Validation item in validations)
                sb.AppendLine("- " + item.Description);

            WriteAlert(sb.ToString());
        }

        public void WriteAlert(string message)
        {
            MessageBox.Show(message, this.Text, MessageBoxButtons.OK, MessageBoxIcon.Exclamation);
        }

        #endregion [ Log ]

        #region [ Eventos ]

        protected override void OnLoad(EventArgs e)
        {
            lblLog.SetVisible(true);
            ListProducts();
            ListPerfils();
            lblLog.Text = string.Empty;
            SetInformations();
        }

        private void cmbProduct_SelectedIndexChanged(object sender, EventArgs e)
        {
            cmbEnvironment.Items.Clear();
            cmbEnvironment.Text = string.Empty;

            cmbVersions.Items.Clear();
            cmbVersions.Text = string.Empty;

            lblVersion.Enabled = false;
            cmbVersions.Enabled = false;
            
            ListEnvironment();
        }

        private void btnExecutar_Click(object sender, EventArgs e)
        {
            Thread th = new Thread(new ParameterizedThreadStart((o) =>
            {
                Execute();
            }));
            th.Start();
        }

        private void cmbEnvironment_SelectedIndexChanged(object sender, EventArgs e)
        {
            cmbVersions.Items.Clear();
            cmbVersions.Text = string.Empty;
            ListVersions();
        }
        #endregion [ Eventos ]

        private void linkManualSetup_LinkClicked(object sender, LinkLabelLinkClickedEventArgs e)
        {
            Entity.Product produt = cmbProduct.GetSelectedItem() as Entity.Product;
            Entity.Environment environment = cmbEnvironment.GetSelectedItem() as Entity.Environment;

            SetupLauncher.Domain.Logic.Setup.ShowManualSetup(produt.ManualSetupPath, environment.WorkSpacePath);
        }
    }
}
